package org.groovyflow.util

/**
 * @author Chuck Tassoni
 */

class ComplexRule extends Rule{
  public static final String AND = "AND"
  public static final String OR = "OR"

  private  List<Closure> predList
  private final Closure impl
  private String type

  def ComplexRule(List<Closure> pred, Closure action, String type) {
    super(null, action)
    this.setPredList(pred)
    this.type = type
  }

  public void setPredList(List<Closure> predList){
    this.predList  = predList
    makeImpl()
  }
  //These predicates can't expect to return anything other than a boolean, because
  //they can't know which one will do the returning.
  //If we ever required actions to declare args passed by predicates before
  //the args set by decision.args() we couldn't get away with this.
  //TODO I'm really wondering if I need ClosureHelp at all given Object ... args
  //See http://groovy.codehaus.org/Extended+Guide+to+Method+Signatures
  private void makeImpl() {
    impl = {Object... args ->
      boolean answer = type != OR
      for (Closure clos in predList) {
        Object decisionBasis = clos(args) //ClosureHelp.invokeClosure(clos, args)
        boolean bool = !(decisionBasis == null || (decisionBasis instanceof Boolean && !decisionBasis))
        if (OR == type && bool) {
          answer = true
          break
        }
        else if (AND == type && !bool) {
          answer = false
          break
        }
      }
      return answer
    }
  }

  public Closure getPred(){
    return impl
  }

 @Override 
 public Rule setPredicateDelegate(Object obj){
   predList.each{Closure clos -> clos.delegate = obj}
   this
 }

}
